package com.fz.us.oa.web.controller.com;

import com.fz.us.admin.base.bean.BaseEnumManager;
import com.fz.us.admin.base.bean.search.order.Order;
import com.fz.us.admin.base.bean.search.result.SearchResultPaging;
import com.fz.us.admin.base.bean.search.rule.Rule;
import com.fz.us.admin.base.bean.search.rule.RuleHelper;
import com.fz.us.admin.base.utils.DataUtil;
import com.fz.us.admin.company.bean.FlowEnum;
import com.fz.us.admin.company.entity.Company;
import com.fz.us.admin.company.entity.Remind;
import com.fz.us.admin.company.entity.TaskEntity;
import com.fz.us.admin.company.entity.User;
import com.fz.us.admin.company.service.DutyService;
import com.fz.us.admin.company.service.RemindService;
import com.fz.us.admin.company.service.TaskEntityService;
import com.fz.us.admin.company.service.UserService;
import com.fz.us.admin.dict.entity.DictItem;
import com.fz.us.admin.dict.service.DictItemService;
import com.fz.us.oa.core.entity.com.Schedule;
import com.fz.us.oa.core.service.com.ScheduleService;
import com.fz.us.oa.web.controller.BaseController;
import com.fz.us.oa.web.shiro.bind.annotation.CurrentUser;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by ZhuChunXiao on 2017/7/20.
 */
@Controller
@RequestMapping(value = "/com/schedule")
public class ScheduleController extends BaseController {
    private static final long serialVersionUID = -654035799856049919L;

    @Autowired
    private UserService userService;
    @Autowired
    private DictItemService dictItemService;
    @Autowired
    private ScheduleService scheduleService;
    @Autowired
    private DutyService dutyService;
    @Autowired
    private TaskEntityService taskEntityService;
    @Autowired
    private RemindService remindService;

    /**
     * 新建，编辑页面
     */
    @RequestMapping(value = "input", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
    public String input(@CurrentUser User user, Model model,String keyId,String draft,String index,String todo,String remind,String record) {
        ArrayList<DictItem> dictItems = getDictItems(user,"scheType");
        if (StringUtils.isNotEmpty(keyId)){
            Schedule schedule=scheduleService.get(keyId);
            model.addAttribute("keyId", keyId);
            model.addAttribute("schedule", schedule);
        }
        model.addAttribute("dictItems", dictItems);
        model.addAttribute("draft", draft);
        model.addAttribute("index", index);
        model.addAttribute("todo", todo);
        model.addAttribute("remind", remind);
        model.addAttribute("record", record);
        return "/com/schedule_input";
    }

    /**
     * 只读页面
     */
    @RequestMapping(value = "read", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
    public String read(@CurrentUser User user, Model model,String keyId,String draft,String index,String todo,String remind,String record,String list) {
        if(StringUtils.isNotEmpty(keyId)) {
            Schedule schedule=scheduleService.get(keyId);
            TaskEntity taskEntity = taskEntityService.getInfoByKeyId(keyId);
            int stepNo = taskEntity.getStepNo();
            String isEdit =  isEdit(keyId);
            model.addAttribute("isEdit", isEdit);
            model.addAttribute("schedule", schedule);
            model.addAttribute("stepNo", stepNo);
        }
        model.addAttribute("keyId", keyId);
        model.addAttribute("draft", draft);
        model.addAttribute("index", index);
        model.addAttribute("todo", todo);
        model.addAttribute("remind", remind);
        model.addAttribute("record", record);
        model.addAttribute("list", list);
        model.addAttribute("user", user);
        return "/com/schedule_read";
    }

    /**
     * 只读页面日历
     */
    @RequestMapping(value = "readDialog", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
    public String readDialog(@CurrentUser User user, Model model,String keyId,String draft,String index,String todo,String remind,String record,String list) {
        if(StringUtils.isNotEmpty(keyId)) {
            Schedule schedule=scheduleService.get(keyId);
            TaskEntity taskEntity = taskEntityService.getInfoByKeyId(keyId);
            int stepNo = taskEntity.getStepNo();
            String isEdit =  isEdit(keyId);
            model.addAttribute("isEdit", isEdit);
            model.addAttribute("schedule", schedule);
            model.addAttribute("stepNo", stepNo);
        }
        model.addAttribute("keyId", keyId);
        model.addAttribute("draft", draft);
        model.addAttribute("index", index);
        model.addAttribute("todo", todo);
        model.addAttribute("remind", remind);
        model.addAttribute("record", record);
        model.addAttribute("list", list);
        model.addAttribute("user", user);
        return "/com/schedule_read";
    }

    /**
     * 保存Model数据
     */
    private Schedule saveModel(User user, String keyId, String dictItemId, String subject,
                               String datStart, String timStart, String datEnd, String timEnd,
                               String userIds, String isPublic,String address) throws ParseException {

        Schedule schedule = null;
        if (StringUtils.isBlank(keyId)) {
            schedule = new Schedule();
            schedule.setCreater(user);
            schedule.setCompany(user.getCompany());

            schedule.setName("日程类型");
        } else {
            schedule = scheduleService.get(keyId);
        }

        if (StringUtils.isNotBlank(dictItemId)) {
            DictItem dictItem = dictItemService.get(dictItemId);
            schedule.setScheDictItem(dictItem);
            schedule.setName(dictItem.getName());
        }

        if (StringUtils.isNotBlank(subject)) {
            schedule.setSubject(subject);
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd hh:mm");
        if (StringUtils.isNotBlank(datStart)) {
            schedule.setDatStart(sdf.parse(datStart));
            if (StringUtils.isNotBlank(timStart)) {
                schedule.setTimStart(sdf2.parse(datStart + " " + timStart));
            }
        }

        if (StringUtils.isNotBlank(datEnd)) {
            schedule.setDatEnd(sdf.parse(datEnd));
            if (StringUtils.isNotBlank(timEnd)) {
                schedule.setTimEnd(sdf2.parse(datEnd + " " + timEnd));
            }
        }

        if (StringUtils.isNotBlank(userIds)) {
            String[] uids = StringUtils.split(userIds,",");
            HashSet<User> users = new HashSet<User>();
            for (String uid : uids) {
                User u = userService.get(uid);
                users.add(u);
            }
            schedule.setParticipants(users);
        }

        if (StringUtils.isNotBlank(isPublic)) {
            schedule.setIsPublic(Integer.valueOf(isPublic));
        }

        if (StringUtils.isNotBlank(address)) {
            schedule.setAddress(address);
        }

        if (schedule.getForm() == null) {
            schedule.setForm("日程安排登记表");
        }

        return schedule;
    }

    /**
     * 保存操作
     */
    @RequestMapping(value = "save", method = RequestMethod.POST)
    public Object save(@CurrentUser User user,
                       @RequestParam(required = false) String keyId, String dictItemId, String subject,
                       String datStart, String timStart, String datEnd, String timEnd,
                       String userIds, String isPublic,String address) throws ParseException {

        Map<String,Object> rMap=new HashMap<String,Object>();
        Schedule schedule = saveModel(user,keyId,dictItemId,subject,datStart,timStart,datEnd,timEnd,userIds,isPublic,address);

        if(StringUtils.isNotEmpty(keyId)){
            scheduleService.update(schedule);
            rMap.put("message", "更新成功");
            //如果是归档后的日程修改，发送提醒
            if(schedule.getProcessState().name().equals("Finished")){
                for(User joinUser:schedule.getParticipants()){
                    Remind remind = new Remind();
                    remind.setUser(joinUser);
                    remind.setBussinessKey("schedule");
                    remind.setKeyId(keyId);
                    remind.setContent(DataUtil.DateToString(schedule.getDatStart())+"的 "+schedule.getSubject()+" 日程已发生变更，请注意查看最新安排");
                    remindService.save(remind);
                }
            }
        } else {
            scheduleService.save(schedule, "com.fz.us.oa.core.entity.com.Schedule");
            rMap.put("message", "保存成功");
        }
        rMap.put("state", "1");
        rMap.put("keyId", keyId);
        return ajaxJson(rMap);
    }

    /**
     * 提交操作
     */
    @RequestMapping(value = "submit", method = RequestMethod.POST)
    public Object submit(@CurrentUser User user,
                         @RequestParam(required = false) String keyId, String dictItemId, String subject,
                         String datStart, String timStart, String datEnd, String timEnd,
                         String userIds, String isPublic,String address, String curDutyId, String comment) throws ParseException {

        Map<String,Object> rMap=new HashMap<String,Object>();
        Schedule schedule = saveModel(user,keyId,dictItemId,subject,datStart,timStart,datEnd,timEnd,userIds,isPublic,address);

        if (StringUtils.isNotEmpty(keyId)) {
            scheduleService.approve(schedule, dutyService.get(curDutyId), comment);
        } else {
            scheduleService.commit(schedule, "com.fz.us.oa.core.entity.com.Schedule", dutyService.get(curDutyId));
        }

        if(schedule.getProcessState().name().equals("Finished")){
            doFinished(schedule);
        }

        rMap.put("message","提交成功");
        rMap.put("state","1");
        rMap.put("keyId", keyId);
        return ajaxJson(rMap);
    }

    //审批
    @RequestMapping(value = "approve", method = RequestMethod.POST)
    public Object approve(@CurrentUser User user, String keyId,  String curDutyId, String comment){
        Map<String,Object> rMap=new HashMap<String,Object>();
        Schedule schedule=scheduleService.get(keyId);
        scheduleService.approve(schedule, dutyService.get(curDutyId), comment);

        //归档后发送提醒
        if(schedule.getProcessState().name().equals("Finished")){
            doFinished(schedule);
        }

        rMap.put("message","提交成功");
        rMap.put("state","1");
        rMap.put("keyId", keyId);
        return ajaxJson(rMap);
    }

    public void doFinished(Schedule schedule){
        for(User joinUser:schedule.getParticipants()){
            Remind remind = new Remind();
            remind.setUser(joinUser);
            remind.setBussinessKey("schedule");
            remind.setKeyId(schedule.getId());
            remind.setContent("您有一条新的日程安排，请查看");
            remindService.save(remind);
        }
    }

    /**
     * 退回
     * @return
     */
    @RequestMapping(value = "back", method = RequestMethod.POST)
    public Object back(@CurrentUser User user, String keyId,String curDutyId, String comment) {
        if (StringUtils.isNotEmpty(keyId)) {
            Schedule schedule=scheduleService.get(keyId);
            scheduleService.back(schedule, dutyService.get(curDutyId), comment);
        }
        Map<String,Object> rMap=new HashMap<String,Object>();
        rMap.put("message","退回成功");
        rMap.put("state","1");
        rMap.put("keyId", keyId);
        return ajaxJson(rMap);
    }
    /**
     * 否决
     * @return
     */
    @RequestMapping(value = "deny", method = RequestMethod.POST)
    public Object deny(@CurrentUser User user, String keyId,String curDutyId, String comment) {
        if (StringUtils.isNotEmpty(keyId)) {
            Schedule schedule=scheduleService.get(keyId);
            scheduleService.deny(schedule, dutyService.get(curDutyId), comment);
        }
        Map<String,Object> rMap=new HashMap<String,Object>();
        rMap.put("message","否决成功");
        rMap.put("state","1");
        rMap.put("keyId", keyId);
        return ajaxJson(rMap);
    }

    /**
     * 列表
     */
    @RequestMapping(value = "list", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String, Object> list(@CurrentUser User user,
                                    @RequestParam() int catalog, @RequestParam() String start, @RequestParam() String end) throws ParseException{
        Company company = user.getCompany();
        // 排序
        Order order = null;

        SearchResultPaging searchResult = null;
        Map<String,Object> params = new HashMap<String,Object>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<Rule> rules = new ArrayList<Rule>();
        rules.add(RuleHelper.ge("timStart", sdf.parse(start)));
        rules.add(RuleHelper.le("timEnd", sdf.parse(end)));
        params.put("company", company);
        params.put("state", BaseEnumManager.StateEnum.Enable);
            if (catalog==1) {
                //所有
                rules.add(RuleHelper.or(
                        RuleHelper.eq("isPublic", 1),
                        RuleHelper.eq("creater", user),
                        RuleHelper.sql("'" + user.getId() + "' in (select participants_id from us_schedule_sys_user where us_schedule_id = this_.id )")));
                searchResult = scheduleService.paging(null,rules,order,
                        "com.fz.us.oa.core.entity.com.Schedule", new FlowEnum.ProcessState []{FlowEnum.ProcessState.Running, FlowEnum.ProcessState.Backed, FlowEnum.ProcessState.Finished},params);
            }else if(catalog==2){
                //与我相关
                rules.add(RuleHelper.or(
                        RuleHelper.eq("creater", user),
                        RuleHelper.sql("'" + user.getId() + "' in (select participants_id from us_schedule_sys_user where us_schedule_id = this_.id )")));
                searchResult = scheduleService.paging(null,rules,order,
                        "com.fz.us.oa.core.entity.com.Schedule", new FlowEnum.ProcessState []{FlowEnum.ProcessState.Running, FlowEnum.ProcessState.Backed, FlowEnum.ProcessState.Finished},params);
            }

        List<Schedule> scheduleList = searchResult.getList();
        ArrayList<Map<String, Object>> dataRows = new ArrayList<Map<String, Object>>();
        Map<String, Object> data = new HashMap<String, Object>();
        Map<String,Object> rMap;
        for(Schedule schedule: scheduleList){
            rMap = new HashMap<String, Object>();
            rMap.put("id", StringUtils.isEmpty(schedule.getId())?"":schedule.getId());
            rMap.put("name", StringUtils.isEmpty(schedule.getName())?"":schedule.getName());
            rMap.put("subject", StringUtils.isEmpty(schedule.getSubject())?"":schedule.getSubject());
            SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            rMap.put("start", sdf1.format(schedule.getTimStart()));
            rMap.put("end", sdf1.format(schedule.getTimEnd()));

            rMap.put("className", "success");
            dataRows.add(rMap);
        }
        data.put("dataRows", dataRows);
        data.put("page", searchResult.getPageNumber());
        data.put("rows", searchResult.getPageSize());
        data.put("records", searchResult.getTotalCount());
        data.put("total", searchResult.getPageCount());
        return data;
    }

    /**
     * 完成修改操作
     */
    @RequestMapping(value = "update", method = RequestMethod.POST)
    public Object update(@CurrentUser User user,
                         @RequestParam(required = false) String keyId, String dictItemId, String subject,
                         String datStart, String timStart, String datEnd, String timEnd,
                         String userIds, String isPublic,String address) throws ParseException {

        Schedule schedule = saveModel(user,keyId,dictItemId,subject,datStart,timStart,datEnd,timEnd,userIds,isPublic,address);

        if(schedule == null){
            return ajaxJson(resultService.fail("保存业务数据失败！"));
        }

        schedule.setTxtStatus("完成修改");
        return ajaxJson(scheduleService.saveEntity(schedule));
    }

    /**
     * 日程取消
     */
    @RequestMapping(value = "cancel/{keyId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public Object cancel(@CurrentUser User user, Model model,
                         @PathVariable String keyId) {

        Schedule schedule = scheduleService.get(keyId);
        schedule.setState(BaseEnumManager.StateEnum.Disenable);
//        model.addAttribute("keyId", keyId);
//        model.addAttribute("schedule",schedule);
//        model.addAttribute("user",user);

        return ajaxJson(scheduleService.saveEntity(schedule));
    }

}
